package de.unikoblenz.west.csxpoi.server;

import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;

import javax.servlet.http.HttpServletResponse;

import org.openrdf.model.Literal;
import org.openrdf.model.URI;
import org.openrdf.model.Value;

/**
 * Writes RDF triples.
 */
public class RdfWriter {

	/**
	 * the content type and encoding for N3
	 */
	private static final String N3_CONTENT_TYPE = "text/rdf+n3; charset=\"utf-8\"";

	/**
	 * returns an RDF triple with a literal or URI object as String. *
	 * 
	 * @param subject
	 *            the subject of the RDF triple
	 * @param predicate
	 *            @ the predicate of the RDF triple
	 * @param object
	 *            the object of the RDF triple
	 * @return RDF triple string
	 */
	public static String getTripleAsString(Value subject, Value predicate,
			Value object) {

		ByteArrayOutputStream myStream = new ByteArrayOutputStream();
		PrintWriter myWriter = new PrintWriter(myStream);
		writeNTriple(myWriter, subject, predicate, object);
		return myStream.toString();

	}

	/**
	 * Writes an RDF triple with a literal or URI object.
	 * 
	 * @param writer
	 *            a writer to write to
	 * @param subject
	 *            the subject of the RDF triple
	 * @param predicate
	 *            @ the predicate of the RDF triple
	 * @param object
	 *            the object of the RDF triple
	 */
	public static void writeNTriple(PrintWriter writer, Value subject,
			Value predicate, Value object) {
		try {
			writeNTriple(writer, (URI) subject, (URI) predicate,
					(Literal) object);
		} catch (ClassCastException e) {
			writeNTriple(writer, (URI) subject, (URI) predicate, (URI) object);
		}
	}

	/**
	 * Writes an RDF triple with an URI object.
	 * 
	 * @param writer
	 *            a writer to write to
	 * @param subject
	 *            the subject of the RDF triple
	 * @param predicate
	 *            the predicate of the RDF triple
	 * @param object
	 *            the object of the RDF triple
	 */
	public static void writeNTriple(PrintWriter writer, URI subject,
			URI predicate, URI object) {
		writer.println("<" + subject.stringValue() + ">" + " <"
				+ predicate.stringValue() + ">" + " <" + object.stringValue()
				+ "> .");
	}

	/**
	 * Writes an RDF triple with a literal object.
	 * 
	 * @param writer
	 *            a writer to write to
	 * @param subject
	 *            the subject of the RDF triple
	 * @param predicate
	 *            the predicate of the RDF triple
	 * @param object
	 *            the object of the RDF triple
	 */
	public static void writeNTriple(PrintWriter writer, URI subject,
			URI predicate, Literal object) {
		writer.println("<" + subject.stringValue() + ">" + " <"
				+ predicate.stringValue() + ">" + " \"" + object.stringValue()
				+ "\"^^<" + object.getDatatype().stringValue() + "> .");
	}

	/**
	 * Sets the content type of the response to N3.
	 * 
	 * @param response
	 *            the response for which to set the content type
	 */
	public static void setN3ContentType(HttpServletResponse response) {
		response.setContentType(N3_CONTENT_TYPE);
	}

}
